﻿#pragma once

#include "../../MirControls/MirImageControl.h"
#include "../../MirControls/MirButton.h"
#include "../../MirControls/MirLabel.h"
#include "../../../Shared/Data/ClientData.h"
#include "../../Settings.h"
#include "../../MirControls/MirControl.h"
#include "../../../Shared/Data/ItemData.h"
#include "../../../Shared/Data/SharedData.h"
#include <string>
#include <vector>
#include <algorithm>
#include <cmath>
#include <any>
#include "../../../tangible_event.h"
#include "../../../stringhelper.h"

//C# TO C++ CONVERTER NOTE: Forward class declarations:
namespace Client::MirScenes::Dialogs { class QuestMessage; }
namespace Client::MirScenes::Dialogs { class QuestRewards; }
namespace Client::MirScenes::Dialogs { class QuestRow; }
namespace Client::MirScenes::Dialogs { class QuestGroupQuestItem; }
namespace Client::MirScenes::Dialogs { class QuestCell; }
namespace Client::MirScenes::Dialogs { class QuestSingleQuestItem; }

using namespace Client::MirControls;
using namespace Client::MirGraphics;
using namespace Client::MirNetwork;
using namespace Client::MirObjects;
using namespace Client::MirSounds;
namespace S = ServerPackets;
namespace C = ClientPackets;

namespace Client::MirScenes::Dialogs
{
    class QuestListDialog final : public MirImageControl
    {
    private:
        MirButton *const _acceptButton, *const _finishButton;
        MirLabel *_availableQuestLabel;

    public:
        std::vector<ClientQuestProgress*> Quests = std::vector<ClientQuestProgress*>();

        int SelectedIndex = 0;

        ClientQuestProgress *SelectedQuest;
        QuestMessage *Message;
        QuestRewards *Reward;

        std::vector<QuestRow*> Rows = std::vector<QuestRow*>(5);

        int StartIndex = 0;

        unsigned int CurrentNPCID = 0;

        virtual ~QuestListDialog()
        {
            delete _acceptButton;
            delete _finishButton;
            delete _availableQuestLabel;
            delete SelectedQuest;
            delete Message;
            delete Reward;
        }

        QuestListDialog();

        void Show() override;

        void Hide() override;

        void Toggle();

        void DisplayInfo();

        void Reset();

        bool GetAvailableQuests();

        void RefreshInterface();

        void UpdateRows();

        void ReDisplayButtons();

        int FindSelectedIndex();

    protected:
        void Dispose(bool disposing) override;

    };
    class QuestDetailDialog final : public MirImageControl
    {
    private:
        MirButton *const _shareButton, *const _pauseButton, *const _cancelButton;

    public:
        ClientQuestProgress *Quest;
        QuestMessage *Message;
        QuestRewards *Reward;

        virtual ~QuestDetailDialog()
        {
            delete _shareButton;
            delete _pauseButton;
            delete _cancelButton;
            delete Quest;
            delete Message;
            delete Reward;
        }

        QuestDetailDialog();

        void DisplayQuestDetails(ClientQuestProgress *quest);

    };
    class QuestDiaryDialog final : public MirImageControl
    {
    public:
        std::vector<ClientQuestProgress*> Quests = std::vector<ClientQuestProgress*>();
        std::vector<QuestGroupQuestItem*> TaskGroups = std::vector<QuestGroupQuestItem*>();

        std::vector<std::string> ExpandedGroups = std::vector<std::string>();

    private:
        MirButton *_closeButton;
        MirLabel *_takenQuestsLabel;

    public:
        virtual ~QuestDiaryDialog()
        {
            delete _closeButton;
            delete _takenQuestsLabel;
        }

        QuestDiaryDialog();

        void DisplayQuests();

        void ClearLog();
        void Show() override;

        void Toggle();

    protected:
        void Dispose(bool disposing) override;
    };
    class QuestTrackingDialog final : public MirImageControl
    {
    public:
        std::vector<int> TrackedQuestsIds = std::vector<int>();
        std::vector<MirLabel*> TaskLines = std::vector<MirLabel*>();

        Font *QuestFont = new Font(Settings::FontName, 8.0F);

    private:
        MirLabel *_questNameLabel, *_questTaskLabel;

    public:
        virtual ~QuestTrackingDialog()
        {
            delete QuestFont;
            delete _questNameLabel;
            delete _questTaskLabel;
        }

        QuestTrackingDialog();

        void DisplayQuests();

        void AddQuest(ClientQuestProgress *quest, bool New = false);

        void RemoveQuest(ClientQuestProgress *quest);

        void UpdateTrackedQuests();

    };

    //Sub controls
    class QuestRow final : public MirControl
    {
    public:
        ClientQuestProgress *Quest;
        MirLabel *NameLabel, *RequirementLabel;
        MirImageControl *SelectedImage, *IconImage;

        bool Selected = false;

        virtual ~QuestRow()
        {
            delete Quest;
            delete NameLabel;
            delete RequirementLabel;
            delete SelectedImage;
            delete IconImage;
        }

        QuestRow();

    private:
        void QuestRow_BeforeDraw(std::any sender, EventArgs *e);

    public:
        void UpdateInterface();

    protected:
        void Dispose(bool disposing) override;
    };
    class QuestMessage final : public MirControl
    {
    public:
        ClientQuestProgress *Quest;
        MirButton *ScrollUpButton, *ScrollDownButton, *PositionBar;

    private:
        static Regex *const C;

        const std::vector<MirLabel*> _textLabel;
//C# TO C++ CONVERTER WARNING: C++ has no equivalent to a 'readonly' collection which allows modification of internal state:
//ORIGINAL LINE: private readonly List<MirLabel> _textButtons = new List<MirLabel>();
        std::vector<MirLabel*> _textButtons = std::vector<MirLabel*>();

    public:
        int TopLine = 0;
        int BottomLine = 0;
        int LineCount = 10;
        bool DisplayProgress = false;

        int PosX = 0, PosMinY = 0, PosMaxY = 0;

        Font *Font = new Font(Settings::FontName, 8.0F);
        std::vector<std::string> CurrentLines = std::vector<std::string>();

    private:
        static const std::string TaskTitle, ProgressTitle;

    public:
        virtual ~QuestMessage()
        {
            delete Quest;
            delete ScrollUpButton;
            delete ScrollDownButton;
            delete PositionBar;
            delete Font;
        }

        QuestMessage(MirButton *scrollUpButton, MirButton *scrollDownButton, MirButton *positionBar, int lineCount, bool displayProgress = false);

    private:
        void QuestMessage_AfterDraw(std::any sender, EventArgs *e);

        void QuestMessage_MouseWheel(std::any sender, MouseEventArgs *e);

        void PositionBar_OnMoving(std::any sender, MouseEventArgs *e);

        void UpdatePositionBar();

    public:
        void UpdateQuest(ClientQuestProgress *quest);

    private:
        void AdjustDescription();

        void NewText(std::vector<std::string> &lines, bool resetIndex = true);

        void NewColour(const std::string &text, const std::string &colour, Point *p);

    protected:
        void Dispose(bool disposing) override;
    };
    class QuestRewards final : public MirControl
    {
    private:
        MirLabel *const _goldLabel, *const _expLabel, *const _creditLabel;

    public:
        ClientQuestProgress *Quest;

        int SelectedItemIndex = -1;
        ItemInfo *SelectedItem = nullptr;

        static std::vector<QuestCell*> FixedItems;
        static std::vector<QuestCell*> SelectItems;

        virtual ~QuestRewards()
        {
            delete _goldLabel;
            delete _expLabel;
            delete _creditLabel;
            delete Quest;
            delete SelectedItem;
        }

        QuestRewards();

        void UpdateRewards(ClientQuestProgress *quest);

    private:
        void QuestReward_BeforeDraw(std::any sender, EventArgs *e);


    public:
        void CleanRewards();

        void UpdateInterface();

        std::vector<QuestItemReward*> FilterRewards(std::vector<QuestItemReward*> &rewardItems);

        int FindSelectedItemIndex();

    protected:
        void Dispose(bool disposing) override;

    };
    class QuestCell final : public MirControl
    {
    private:
        MirLabel *CountLabel;

    public:
        ItemInfo *Item;
        UserItem *ShowItem;
        unsigned short Count = 0;

        bool Selected = false;
        bool Fixed = false;

        virtual ~QuestCell()
        {
            delete Item;
            delete ShowItem;
        }

    private:
        MirLabel *getCountLabel() const;
        void setCountLabel(MirLabel *value);

    public:
        QuestCell();

    protected:
        void OnMouseEnter() override;
        void OnMouseLeave() override;

        void DrawControl() override;

        void Dispose(bool disposing) override;

    private:
        void CreateDisposeLabel();
        void DisposeCountLabel();
    };


    class QuestGroupQuestItem final : public MirControl
    {
    public:
        std::string Group = std::string::Empty;
        std::vector<ClientQuestProgress*> Quests = std::vector<ClientQuestProgress*>();

        bool Expanded = true;
        int SizeY = 15;

    private:
        MirButton *const _expandButton;
        MirLabel *const _groupLabel;
//C# TO C++ CONVERTER WARNING: C++ has no equivalent to a 'readonly' collection which allows modification of internal state:
//ORIGINAL LINE: private readonly List<QuestSingleQuestItem> _tasks = new List<QuestSingleQuestItem>();
        std::vector<QuestSingleQuestItem*> _tasks = std::vector<QuestSingleQuestItem*>();

    public:
        TangibleEvent<EventHandler> *ExpandedChanged = new TangibleEvent<EventHandler>();
        virtual ~QuestGroupQuestItem()
        {
            delete _expandButton;
            delete _groupLabel;
        }

    private:
        void OnExpandedChanged();

    public:
        TangibleEvent<EventHandler> *SelectedQuestChanged = new TangibleEvent<EventHandler>();
    private:
        void OnSelectedQuestChanged(std::any ob);

    public:
        QuestGroupQuestItem(const std::string &group, std::vector<ClientQuestProgress*> &quests, bool expanded);

        void UpdatePositions();

        void ClearTasks();

        void DeselectQuests();

    private:
        void ChangeExpand();

    protected:
        void Dispose(bool disposing) override;
    };
    class QuestSingleQuestItem final : public MirControl
    {
    private:
        MirLabel *_questLabel, *_stateLabel;
        MirImageControl *const _selectedImage;

    public:
        ClientQuestProgress *Quest;

        bool Selected = false;
        bool TrackQuest = false;

        TangibleEvent<EventHandler> *SelectedQuestChanged = new TangibleEvent<EventHandler>();
        virtual ~QuestSingleQuestItem()
        {
            delete _questLabel;
            delete _stateLabel;
            delete _selectedImage;
            delete Quest;
        }

    private:
        void OnSelectedQuestChanged();

    public:
        QuestSingleQuestItem(ClientQuestProgress *quest);

    private:
        void QuestTaskSingleItem_BeforeDraw(std::any sender, EventArgs *e);

        void QuestTaskSingleItem_AfterDraw(std::any sender, EventArgs *e);

    protected:
        void Dispose(bool disposing) override;
    };

}
